package ru.usu.gv.uicomponents;

import ru.usu.gv.core.GraphCanvas;
import ru.usu.gv.styles.StyleFacade;
import ru.usu.gv.uicomponents.viewitems.edge.IEdgeViewItem;

import javax.media.j3d.Appearance;
import javax.media.j3d.BranchGroup;
import javax.media.j3d.ColoringAttributes;
import javax.media.j3d.Geometry;
import javax.media.j3d.Transform3D;
import javax.media.j3d.TransformGroup;
import javax.vecmath.Color3f;

import java.awt.Color;

/**
 @author: Sergey Pupyrev 
 Apr 2, 2006
 */
public class UIEdge extends UIElementBase<IEdgeViewItem>
{
	private IEdgeViewItem viewItem;
	private IUIEdgeType edgeType;

	private UIVertex v1;
	private UIVertex v2;

	public UIEdge(UIVertex v1, UIVertex v2)
	{
		this(v1, v2, StyleFacade.getEdgeType());
	}

	public UIEdge(UIVertex v1, UIVertex v2, String edgeTypeId)
	{
		super();
		this.v1 = v1;
		this.v2 = v2;
		edgeType = UIEdgeTypeRegistry.findEdgeType(edgeTypeId);

		initializeView();
	}

	public void initializeView()
	{
		Appearance appearance = getAppearance();

		setColoringAttributes(appearance);

		viewItem = edgeType.createEdgeViewItem(appearance, getTransformGroup(), v1, v2);
		viewItem.makePickable(this);
		viewItem.setColor(StyleFacade.getEdgeColor());
	}

	private void setColoringAttributes(Appearance appearance)
	{
		ColoringAttributes ca = new ColoringAttributes();
		ca.setShadeModel(ColoringAttributes.NICEST);
		ca.setColor(new Color3f(StyleFacade.getEdgeColor()));
		ca.setCapability(ColoringAttributes.ALLOW_COLOR_WRITE);
		appearance.setColoringAttributes(ca);
	}

	@Override
	public IEdgeViewItem getViewItem()
	{
		return viewItem;
	}

	public UIVertex getV1()
	{
		return v1;
	}

	public UIVertex getV2()
	{
		return v2;
	}

	public double getLength()
	{
		return v1.getPosition().distance(v2.getPosition());
	}

	@Override
	public void draw()
	{
		if (!StyleFacade.isShowEdges())
			return;

		super.draw();

		Geometry geometry = viewItem.buildGeometry();
		setGeometry(geometry);
	}

	public void moveToCanvasPosition(int x, int y)
	{
		viewItem.moveToCanvasPosition(getTransformGroup(), x, y);
		draw();
	}

	@Override
	public void delete()
	{
		super.delete();
		GraphCanvas.getInstance().getCurrentGraph().removeEdge(this);
	}

	@Override
	public void highlight()
	{
		//getViewItem().getAppearance().setMaterial(UIConstants.highlightMaterial);
	}

	@Override
	public void unhighlight()
	{
		//getViewItem().getAppearance().setMaterial(UIConstants.defaulEdgeMaterial);
	}

	public IUIEdgeType getEdgeType()
	{
		return edgeType;
	}

	public void changeEdgeType(IUIEdgeType edgeType)
	{
		if (this.edgeType == edgeType)
			return;

		//TODO: union with vertex??
		this.edgeType = edgeType;

		//recreate BranchGroup
		BranchGroup newBranchGroup = createBranchGroup();
		TransformGroup newTransformGroup = createTransformGroup(newBranchGroup);

		Transform3D transform3D = new Transform3D();
		getTransformGroup().getTransform(transform3D);
		newTransformGroup.setTransform(transform3D);

		//create new ViewItem
		Color oldColor = viewItem.getColor();
		viewItem = edgeType.createEdgeViewItem(getAppearance(), newTransformGroup, v1, v2);
		viewItem.makePickable(this);
		viewItem.setColor(oldColor);

		//remove old BranchGroup
		super.delete();

		//add new one
		setBranchGroup(newBranchGroup);
		setTransformGroup(newTransformGroup);
		initBranchGroup();

		draw();
	}

	public void hide()
	{
		super.delete();
	}

	public void show()
	{
		changeEdgeType(getEdgeType());
	}

	@Override
	public String toString()
	{
		return "[" + getV1().toString() + "-" + getV2().toString() + "]";
	}
}
